import os
import subprocess
import concurrent.futures
import threading
import random
import time
from tqdm import tqdm

import json
import asyncio
import websockets

# 创建一个线程池，控制并发线程数
def run_simulation(item, folder_path, setfos_dir, out_put, runsim):
    if runsim:
        # try:
        item_path = f'{folder_path}\\{item}'
        command = [f"{setfos_dir}setfos-kernel.exe", item_path,f'{out_put}']
        # print(command)
        process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = process.communicate()
        # print(stdout.decode('utf-8'))
        if process.returncode == 0:
            # print(stdout.decode('utf-8',errors='replace'))
            print("")
            
        else:
            print(f"Error: {stderr.decode('utf-8',errors='replace')}")
            return

        new_folder_name = item.split('.par')[0]  # 从item中移除.par后缀
        default_folder_path = out_put
        # print(default_folder_path)
        new_file_name = None  # 在函数开始处初始化new_file_name
        # lock = threading.Lock()
        # with lock:
        if os.path.exists(default_folder_path):
            for file_name in os.listdir(default_folder_path):
                extracted_string = file_name.split('.')[0]

                if 'opt2D' == extracted_string:
                    new_file_name = f'opt2D_{new_folder_name}.txt'
                    old_file_path = os.path.join(default_folder_path, file_name)
                    new_file_path = os.path.join(default_folder_path, new_file_name)
                    os.rename(old_file_path, new_file_path)
            # if new_file_name:  # 确保new_file_name被定义
                # print(f"Renamed files in folder {default_folder_path} to match {new_file_name}")
        else:
            print(f"Folder {default_folder_path} not found")

def Ref_5_10(string1,MAX_THREADS,out_put,setfos_dir,file_number,runsim):
    folder_path = f'.\\{string1}'

    # folder_path = '.\\two_par_result'
    list1 = [filename for filename in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, filename))]

    # 使用 ThreadPoolExecutor 来控制并发线程数
    with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
        futures = []
        # for item in list1:
        for i,item in tqdm(enumerate(list1), desc=f"Processing {string1}", unit='file'):
            # out_put_new=os.path.join(out_put,str(random.randint(1,file_number)))
            out_put_new=os.path.join(out_put,str(i%file_number))
            if not os.path.exists(out_put_new):
                os.makedirs(out_put_new)
            futures.append(executor.submit(run_simulation, item, folder_path,setfos_dir, out_put_new, runsim))

        # 等待所有线程完成
        # for future in concurrent.futures.as_completed(futures):
        count=0
        for future in tqdm(concurrent.futures.as_completed(futures), total=len(futures), desc="Waiting for simulations", unit='simulation'):
            future.result()
            count=count+1

def main(setfos_dir,out_put,MAX_THREADS,file_number):
    print("开始仿真........")
    # setfos_dir = "C:\\Program Files\\Fluxim\\Setfos 5.2 (x64)\\"
    # out_put = "E:\\setfos\\Data\\"
    # print("请输入需要开启的线程数：")
    # while True:
    #     try:
    #         MAX_THREADS = int(input())
    #         break  # 如果输入成功转换为整数，则跳出循环
    #     except ValueError:
    #         print("输入无效，请输入一个数字。")

    # print("请输入需要的存放仿真结果的文件夹数量：4线程，要20个文件夹,8线程，要至少40个文件夹")
    # while True:
    #     try:
    #         file_number = int(input())
    #         break  # 如果输入成功转换为整数，则跳出循环
    #     except ValueError:
    #         print("输入无效，请输入一个数字。")


    runsim = True  # set to True if you also want to run the simulation

    # print('(5 and 10)%  开始仿真')
    # Ref_5_10('finally_par_result', MAX_THREADS, out_put, setfos_dir, file_number,runsim)
    # print('finally_par_result (5 and 10)%仿真结束，开始进行 Ref 仿真')
    # Ref_5_10('two_par_result', MAX_THREADS, out_put, setfos_dir, file_number,runsim)
    # print('Ref仿真结束')

    print("请选择仿真的方式：1:Ref and (5 and 10)% 都仿真，2：只仿真Ref,输入数字 1 或 2 ")
    while True:
        number = input()
        if number in ['1', '2']:
            break  # 如果输入的是1或2，则跳出循环
        else:
            print("输入无效，请输入1或2。")
    if number == '1':
        print('(5 and 10)%  开始仿真')
        Ref_5_10('finally_par_result', MAX_THREADS, out_put, setfos_dir, file_number,runsim)
        print('finally_par_result (5 and 10)%仿真结束，开始进行 Ref 仿真')
        Ref_5_10('two_par_result', MAX_THREADS, out_put, setfos_dir, file_number,runsim)
        print('Ref仿真结束')
    if number == '2':
        print('Ref 开始仿真')
        Ref_5_10('two_par_result', MAX_THREADS, out_put, setfos_dir, file_number,runsim)
        print('Ref仿真结束')



    #     folder_path = '.\\finally_par_result'

    #     # folder_path = '.\\two_par_result'
    #     list1 = [filename for filename in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, filename))]

    #     # 使用 ThreadPoolExecutor 来控制并发线程数
    #     with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
    #         futures = []
    #         for item in list1:
    #             out_put_new=os.path.join(out_put,str(random.randint(1,8)))
    #             if not os.path.exists(out_put_new):
    #                 os.makedirs(out_put_new)
    #             futures.append(executor.submit(run_simulation, item, folder_path,setfos_dir, out_put_new, runsim))

    #         # 等待所有线程完成
    #         for future in concurrent.futures.as_completed(futures):
    #             future.result()
    # else:
    #     # folder_path = '.\\finally_par_result'

    #     folder_path = '.\\two_par_result'
    #     list2 = [filename for filename in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, filename))]

    #     # 使用 ThreadPoolExecutor 来控制并发线程数
    #     with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
    #         futures = []
    #         for item2 in list2:
    #             out_put_new=os.path.join(out_put,str(random.randint(1,8)))
    #             if not os.path.exists(out_put_new):
    #                 os.makedirs(out_put_new)
    #             futures.append(executor.submit(run_simulation, item2, folder_path,setfos_dir, out_put_new, runsim))

    #         # 等待所有线程完成
    #         for future in concurrent.futures.as_completed(futures):
    #             future.result()



# if __name__ == "__main__":
#     main()